﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

using SharedGenomics.Core;
using SharedGenomics.Workbench.Views;
using SharedGenomics.Workbench.PresentationModel;

namespace SharedGenomics.Workbench.Presenters
{
    public class CategoryFilterPresenter : Presenter
    {
        public CategoryFilterPresenter(ICategoryFilterView view, CategoryValueViewFactory valueViewFactory, IEnumerable<ValueDisplayItem<string>> categories, Func<string, IEnumerable<ValueDisplayItem<string>>> categoryValuesFunc)
            : base(view)
        {
            view.ThrowIfNull("view");
            categoryValuesFunc.ThrowIfNull("categoryValuesFunc");
            valueViewFactory.ThrowIfNull("valueViewFactory");

            //register for view events
            view.RemoveClicked += new EventHandler(this.View_RemoveClicked);
            view.SelectedCategoryChanged += new EventHandler(this.View_SelectedCategoryChanged);
            view.AddNewClicked += (o, e) => { this.FilterAdded.Raise(this); };

            this.FilterView = view;
            this.ValueViewFactory = valueViewFactory;
            this.CategoricalColumns = categories ?? Enumerable.Empty<ValueDisplayItem<string>>();
            this.ColumnValuesFunc = categoryValuesFunc;

            //set available categories on view
            this.FilterView.AvailableCategories = this.CategoricalColumns;

            this.ValueViews = new List<ICategoryValueView>();
        }

        protected void OnFilterRemoved()
        {
            this.FilterRemoved.Raise(this);
        }

        private void View_RemoveClicked(object sender, EventArgs e)
        {
            //clean up and notify listeners this filter is being closed
            this.DeregisterViewEvents();
            this.OnFilterRemoved();
        }

        private void View_SelectedCategoryChanged(object sender, EventArgs e)
        {
            this.FilterView.AvailableValues = this.ColumnValuesFunc(this.FilterView.SelectedCategory);
        }

        private void DeregisterViewEvents()
        {
            this.FilterView.RemoveClicked -= this.View_RemoveClicked;
            this.FilterView.SelectedCategoryChanged -= this.View_SelectedCategoryChanged;
        }

        public event EventHandler FilterRemoved;
        public event EventHandler FilterAdded;

        public ICategoryFilterView FilterView { get; private set; }
        public string SelectedCategory
        {
            get { return this.FilterView.SelectedCategory; }
        }

        public IEnumerable<string> SelectedValues
        {
            get { return this.FilterView.SelectedValues; }
        }

        private CategoryValueViewFactory ValueViewFactory { get; set; }
        private IEnumerable<ValueDisplayItem<string>> CategoricalColumns { get; set; }
        private Func<string, IEnumerable<ValueDisplayItem<string>>> ColumnValuesFunc { get; set; }

        private IList<ICategoryValueView> ValueViews { get; set; }
    }
}
